深入解读 RTOS 任务切换
RTOS 任务在时间片切换到来之前,所有代码执行完毕,但是没有阻塞功能的话,此时任务会从头再继续执行一遍,因为所有任务都是一个无限循环的主体。
为什么要在任务创建的时候手动压栈呢?
硬件自动压栈是当触发中断响应例程的时候才会发生,手动创建的任务函数并不是中断程序,所以必须手动为该任务创建现场环境,否则当任务第一次发生切换的时候,就没有可供恢复的现场了。
中断/异常的响应序列分为三步:
- 入栈
- 取向量
- 选取堆栈指针 MSP/PSP,更新堆栈指针 SP,更新连接寄存器 LR,更新程序计数器 PC
入栈操作中值得注意都是,响应异常的第一个行动,就是自动保存现场的必要部分:依次把 XPSR,PC,LR,R12 以及 R3-R0 由硬件自动压入适当的堆栈中:如果当响应异常时,当前的代码正在使用 PSP,则压入 PSP,也就是使用进程堆栈;否则就压入 MSP,使用主堆栈。一旦进入了服务例程,就将一直使用主堆栈。
在启动了中断返回序列后,下列的处理就将进行:
- 出栈:先前压入栈中的寄存器在这里恢复。内部的出栈顺序与入栈时想对应,堆栈指针的值也改回先前的值。
- 更新 NVIC 寄存器:伴随着异常的返回,它的活动位也被硬件清除。对于外部中断,倘若中断输入再次被置为有效,悬起位也将再次置位,新一次的中断响应序列也可随之再次开始。